﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace INF7GEN
{
    /// <summary>
    /// Static class for testing and compiling game code.
    /// </summary>
    static class GenerateCode
    {
        /// <summary>
        /// Debugs global data to see if any anomalies exist then outputs what needs to be fixed.
        /// </summary>
        public static string debug(string[] args, GlobalStates game)
        {
            return "";
        }

        /// <summary>
        /// Compiles global data into Game Code.
        /// </summary>
        public static string Compile(string[] args, GlobalStates game)
        {
            StringBuilder code = new StringBuilder();
            //author/game info
            if (game.ProjectName.Length > 0 && game.AuthorName.Length > 0)
            {
                code.Append('"'); code.Append(game.ProjectName); code.Append('"'); code.Append(" by "); code.AppendLine(game.AuthorName); code.AppendLine("");
            }
            if (game.StoryHeadline.Length > 0)
            {
                code.Append("The story headline is "); code.Append('"'); code.Append("" + game.StoryHeadline); code.Append('"'); code.AppendLine(".");
            }
            if(game.Extensions.ADVENTUREBOOK)
            {
                code.AppendLine("\nInclude Adventure Book by Edward Griffiths");
                //compile adventure book code here//
                foreach (ADVBookPage p in game.Extensions.ListOfPages)
                {
                    //if this page is the first page of the game
                    if (p.FirstPage) { code.Append("\nThe First Page is a page.\nIt is followed by " + p.InternalName + "."); }

                    code.Append("\n\n" + p.InternalName + " is a page.");

                    if (p.DefaultPageContent != "")
                    {
                        code.Append("\n" + "\"" + p.DefaultPageContent + "\".");
                    }

                    if (p.DeadEnd)//ends here and goes back to it's parent page
                    {
                        code.Append("\nIt is a dead end.");
                    }
                    else if (p.LinearMove && p.FollowingPage != "")//no choices, moves directly to another page
                    {
                        code.Append("\nIt is followed by " + p.FollowingPage);
                    }
                    else//runs choices
                    {
                        foreach (ADVBookChoice c in p.ListOfChoices)
                        {
                            code.Append("\nA choice called " + c.InternalName + " is for " + p.InternalName + ". ");

                            if (c.Text != "")
                            {
                                code.Append("\n" + "\"" + c.Text + "\".");
                            }

                            if (c.Triggers != "")
                            {
                                code.Append("\nIt triggers " + c.Triggers + " .");
                            }
                        }
                    }
                }

                //--------------------------//
            }
            else//Adventure book does not use the standard coding used, and needs to be compiled seperatly
            {

                code.AppendLine("A boy is a kind of person.\nA girl is a kind of person.");
                code.Append("\n");

                //Usercommands-------------------
                foreach (UserCommand uc in game.UserCommands)
                {
                    if (uc.IsStandardCommand)//only standard commands are generated in the following way
                    {
                        code.AppendLine("After reading a command:");
                        code.Append("   if the player's command "); code.Append("" + UserCommand.Logic[uc.ChosenLogic]); code.Append(" "); code.Append('"'); code.Append("" + uc.LogicTestString); code.Append('"'); code.Append(", ");
                        code.Append("" + UserCommand.Action[uc.ChosenAction]); code.Append(" the "); code.Append("" + UserCommand.Arguments[uc.ChosenArgument]);
                        if (uc.ChosenAction != 1)//not a cut action
                        {
                            code.Append(" with "); code.Append('"'); code.Append("" + uc.ReplacementString); code.Append('"');
                        }
                    }
                    else//custom built commands, comming later...
                    {
                    }
                    code.Append(".");
                    code.Append("\n");
                }
                //-------------------------------








                //Rooms--------------------------
                foreach (Room r in game.Rooms)
                {
                    code.Append("RM" + r.InternalName + " is a ");
                    if (r.RoomIsDark)
                        code.Append("dark ");
                    code.AppendLine("room.");

                    if (r.Description.Length > 0)
                    {
                        code.Append('"');
                        code.Append("" + r.Description);
                        code.Append('"');
                        code.AppendLine(".");
                    }

                    if (r.PrintedName.Length > 0)
                    {
                        code.Append("The printed name of RM" + r.InternalName + " is "); code.Append('"'); code.Append("" + r.PrintedName); code.Append('"'); code.AppendLine(".");
                    }
                    code.Append("\n");
                }
                //-------------------------------








                //Room connections---------------
                foreach (Room r in game.Rooms)
                {
                    if (r.LinkedRooms[0] != null)
                        code.Append("" + r.LinkedRooms[0].InternalName + " is north of RM" + r.InternalName + ". ");
                    if (r.LinkedRooms[1] != null)
                        code.Append("" + r.LinkedRooms[1].InternalName + " is east of RM" + r.InternalName + ". ");
                    if (r.LinkedRooms[2] != null)
                        code.Append("" + r.LinkedRooms[2].InternalName + " is south of RM" + r.InternalName + ". ");
                    if (r.LinkedRooms[3] != null)
                        code.Append("" + r.LinkedRooms[3].InternalName + " is west of RM" + r.InternalName + ". ");
                    if (r.LinkedRooms[4] != null)
                        code.Append("" + r.LinkedRooms[4].InternalName + " is above RM" + r.InternalName + ". ");
                    if (r.LinkedRooms[5] != null)
                        code.Append("RM" + r.InternalName + " is above " + r.LinkedRooms[5].InternalName + ". ");


                }
                //-------------------------------








                code.Append("\n\n");
                //things-------------------------
                //The internalname is a thing. The printed name is "printedname". The plural of internalname is pluralname. The indefinite article is "indefinitearticle".
                // The inventory listing is "InventoryListing".
                foreach (Thing t in game.Things)
                {

                    code.Append("The " + t.InternalName + " is a ");

                    if (t.KindOf)
                        code.Append("kind of ");

                    //custom type check
                    if (t.Type != -1)
                        code.AppendLine(GlobalStates.type[t.Type] + ".");
                    else if (t.CustomType.Length > 0)
                        code.AppendLine(t.CustomType + ".");
                    else if (t.ThingType != null)
                        code.AppendLine("" + t.ThingType.InternalName + ".");
                    else
                        code.AppendLine("thing.");

                    if (t.PrintedName != "")
                    {
                        code.Append("The printed name is "); code.Append('"'); code.Append("" + t.PrintedName); code.Append('"'); code.AppendLine(".");
                    }
                    if (t.PluralName != "")
                    {
                        code.AppendLine("The plural of " + t.InternalName + " is " + t.PluralName + ".");
                    }
                    if (t.IndefiniteArticle != "")
                    {
                        code.Append("The indefinite article is "); code.Append('"'); code.Append("" + t.IndefiniteArticle); code.Append('"'); code.AppendLine(".");
                    }
                    if (t.InventoryListing != "")
                    {
                        code.Append("The inventory listing is "); code.Append('"'); code.Append("" + t.InventoryListing); code.Append('"'); code.AppendLine(".");
                    }

                    if (t.PluralNamed && t.ProperNamed)
                    {
                        code.AppendLine("It is plural-named and proper-named.");
                    }
                    else if (t.ProperNamed && (!t.PluralNamed))
                    {
                        code.AppendLine("It is proper-named.");
                    }
                    else if (t.PluralNamed && (!t.ProperNamed))
                    {
                        code.AppendLine("It is plural-named.");
                    }

                    code.Append("\n\n");
                }

                //---------------------------------





                code.Append("\n\n");
                //Actions--------------------------
                foreach (Action a in game.Actions)
                {
                    code.Append(a.NameOfAction + " is an action applying to " + Action.NumberOfObjects[a.ChosenNumberOfObjects] + " " + Action.Requirenments[a.ChosenRequirenment] + " " + a.TypeOfObject + " " + Action.OptionalLit[a.ChosenOptionalLit] + ".");
                    code.Append("\n\n");
                }
                //-------------------------------
            }







            return code.ToString();
        }

    }
}
